package com.stud.common.utils;

import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collection;
import java.util.Objects;

/**
 * @author Stud
 * @title 乱七八糟工具类
 * @desription XXXXX
 * @data 2022-09-27 10:31
 */
@Slf4j
public class Toolkit {

    public static final String[] FILTER_CHARS = {"drop ", "select ", "delete ", "update ", "insert ", "or ", "and ", "where ", "add ", "script", "\\", "\"", "'", "$", "(", ")", "+", "%", "<", ">", "@"};
    public static final String[] REPLACE_CHARS = {"ｄｒｏｐ ", "ｓｅｌｅｃｔ ", "ｄｅｌｅｔｅ ", "ｕｐｄａｔｅ ", "ｉｎｓｅｒｔ ", "ｏｒ ", "ａｎｄ ", "ｗｈｅｒｅ ", "ａｄｄ ", "ｓｃｒｉｐｔ", "＼", "“", "＇", "＄", "（", "）", "＋", "％", "＜", "＞", "＠"};


    public static int object2Int(Object o) {
        return object2Int(o, 0);
    }

    public static int object2Int(Object o, Integer defaultValue) {
        if (Objects.isNull(o)) {
            return defaultValue;
        }
        try {
            return Double.valueOf(o.toString()).intValue();
        } catch (Exception e) {
            return defaultValue;
        }
    }

    public static Double object2Double(Object o) {
        return object2Double(o, 0D);
    }

    public static Double object2Double(Object o, int scale) {
        BigDecimal bigDecimal = format2BigDecimal(o, scale);
        if (Objects.isNull(bigDecimal)) {
            return 0D;
        }

        return object2BigDecimal(formatBigDecimal(bigDecimal)).doubleValue();
    }

    public static Double object2Double(Object o, Double defaultValue) {
        if (Objects.isNull(o)) {
            return defaultValue;
        }
        try {
            return Double.valueOf(object2String(o));
        } catch (Exception e) {
            return defaultValue;
        }
    }

    public static Long object2Long(Object o) {
        return object2Long(o, 0L);
    }

    public static Long object2Long(Object o, Long defaultValue) {
        if (Objects.isNull(o)) {
            return defaultValue;
        }
        try {
            return Long.valueOf(o.toString());
        } catch (Exception e) {
            return defaultValue;
        }
    }

    public static String object2String(Object o) {
        if (Objects.isNull(o)) {
            return "";
        }
        return o.toString();
    }

    public static String stringVal(Object o) {
        if (Objects.isNull(o)) {
            return null;
        }
        return o.toString();
    }

    public static String removeLastCode(Object str, String code) {
        String result = "";

        String s = getStringVal(str);

        if (StringUtils.isBlank(s) || StringUtils.isBlank(code)) {
            return result;
        }

        result = str.toString().trim();
        code = code.trim();

        if (result.endsWith(code)) {
            return result.substring(0, result.length() - code.length());
        }
        return result;
    }

    public static String Obj2InWithQuotes(Object... obj) {
        String result = StringUtils.join(obj, "','");
        return "'" + result + "'";
    }

    public static String Obj2InWithQuotes(Collection<?> list) {
        String result = StringUtils.join(list.toArray(), "','");
        return "'" + result + "'";
    }

    public static String Obj2In(Object... obj) {
        String result = StringUtils.join(obj, ",");
        return result;
    }

    public static String Obj2In(Collection<?> list) {
        String result = StringUtils.join(list, ",");
        return result;
    }

    /**
     * 英文后面紧跟着空格才会被替换 把-也过滤了,防止注释
     *
     * @param s
     * @return
     * @codes drop ｄｒｏｐ
     * @codes select ｓｅｌｅｃｔ
     * @codes delete ｄｅｌｅｔｅ
     * @codes update ｕｐｄａｔｅ
     * @codes insert ｉｎｓｅｒｔ
     * @codes or ｏｒ
     * @codes and ａｎｄ
     * @codes where ｗｈｅｒｅ
     * @codes add ａｄｄ
     * @codes \＼
     * @codes /／
     * @codes "“
     * @codes '＇
     * @codes $＄
     * @codes (（
     * @codes )）
     * @codes +＋
     * @codes -－
     * @codes %％
     * @codes <＜
     * @codes >＞
     * @codes @＠
     */
    public static String xssEncode(String s) {
        if (StringUtils.isEmpty(s)) {
            return s;
        }
        String lower = s.toLowerCase();
        for (int i = 0; i < FILTER_CHARS.length; i++) {
            int start = lower.indexOf(FILTER_CHARS[i]);
            if (start > -1) {
                String zwFilter = s.substring(start, start + FILTER_CHARS[i].length());
                s = s.replace(zwFilter, REPLACE_CHARS[i]);
            }
        }
        return s;
    }

    public static String xssDecode(String s) {
        if (StringUtils.isEmpty(s)) {
            return s;
        }
        String lower = s.toLowerCase();
        for (int i = 0; i < REPLACE_CHARS.length; i++) {
            int start = lower.indexOf(REPLACE_CHARS[i]);
            if (start > -1) {
                String zwFilter = s.substring(start, start + REPLACE_CHARS[i].length());
                s = s.replace(zwFilter, FILTER_CHARS[i]);
            }
        }
        return s;
    }

    public static boolean isEmptyOrZero(Object value) {
        if (Objects.isNull(value))
            return true;
        try {
            return (new BigDecimal(value.toString()).doubleValue() == 0.0);
        } catch (Exception e) {
            return true;
        }
    }

    public static BigDecimal getBigDecimalVal(Object data) {
        if (data == null) {
            return null;
        } else {
            try {
                return new BigDecimal(data.toString());
            } catch (Exception e) {
                return null;
            }
        }
    }

    public static Float objectToFloat(Object obj) {
        return objectToFloat(obj, 0F);
    }

    public static Float objectToFloat(Object obj, Float defaultValue) {
        if (Objects.isNull(obj))
            return defaultValue;
        try {
            return Float.valueOf(obj.toString());
        } catch (Exception e) {
            return defaultValue;
        }
    }

    public static String getStringVal(Object obj) {
        return getStringVal(obj, "");
    }

    public static String getStringVal(Object obj, String defaultStr) {
        if (Objects.isNull(obj)) {
            return defaultStr;
        } else {
            return obj.toString();
        }
    }

    public static String formatBigDecimal(Object value) {
        return formatBigDecimal(value, 1);
    }

    public static String formatBigDecimal(Object value, int scale) {
        if (Objects.isNull(value)) {
            return "";
        }
        BigDecimal num = format2BigDecimal(value, scale);
        return String.valueOf(num);
    }

    public static BigDecimal format2BigDecimal(Object value, int scale) {
        BigDecimal num = getBigDecimalVal(value);
        if (Objects.isNull(num)) {
            return null;
        }
        return num.setScale(scale, RoundingMode.HALF_UP);
    }

    public static BigDecimal object2BigDecimal(Object data) {
        if (data == null) {
            return new BigDecimal(0);
        } else {
            try {
                return new BigDecimal(data.toString());
            } catch (Exception e) {
                return new BigDecimal(0);
            }
        }
    }

    /**
     * 加法
     *
     * @param nums
     * @return
     */
    public static BigDecimal bigDecimalAdd(Object... nums) {
        if (Objects.isNull(nums)) {
            return null;
        }
        BigDecimal result = new BigDecimal(0);

        for (Object temp : nums) {
            result = result.add(object2BigDecimal(temp));
        }
        return result;
    }

    /**
     * 减法
     *
     * @param num1
     * @param num2
     * @return
     */
    public static BigDecimal bigDecimalSubtract(Object num1, Object num2) {
        if (Objects.isNull(num1)) {
            return null;
        }
        if (Objects.isNull(num2)) {
            return getBigDecimalVal(num1);
        }
        return object2BigDecimal(num1).subtract(object2BigDecimal(num2));
    }

    /**
     * 乘法
     *
     * @param num1
     * @param num2
     * @return
     */
    public static BigDecimal bigDecimalMultiply(Object num1, Object num2) {
        if (Objects.isNull(num1) || Objects.isNull(num2)) {
            return new BigDecimal(0);
        }
        return object2BigDecimal(num1).multiply(object2BigDecimal(num2));
    }

    /**
     * 除法
     *
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal bigDecimalDivide(Object a, Object b) {
        return bigDecimalDivide(a, b, 1);
    }

    /**
     * 除法
     *
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal bigDecimalDivide(Object a, Object b, int scale) {
        if (isEmptyOrZero(a) || isEmptyOrZero(b)) {
            return new BigDecimal(0);
        }
        return getBigDecimalVal(a).divide(getBigDecimalVal(b), scale, RoundingMode.HALF_UP);
    }

    public static int[] strings2ints(String[] ss) {
        if (Objects.isNull(ss) || ss.length == 0) {
            return null;
        }
        int len = ss.length;
        int[] result = new int[len];
        int i = 0;
        for (String s : ss) {
            result[i++] = object2Int(s);
        }
        return result;
    }

    public static String formatNum(Object num, String defaultValue) {
        String s = String.valueOf(num);
        if (Objects.isNull(num)) {
            return defaultValue;
        }
        if (!s.contains(".")) {
            return s;
        }
        if (s.endsWith("000000")) {
            s = s.substring(0, s.length() - 6);
        }
        if (s.endsWith("00000")) {
            s = s.substring(0, s.length() - 5);
        }
        if (s.endsWith("0000")) {
            s = s.substring(0, s.length() - 4);
        }
        if (s.endsWith("000")) {
            s = s.substring(0, s.length() - 3);
        }
        if (s.endsWith("00")) {
            s = s.substring(0, s.length() - 2);
        }
        if (s.endsWith("0")) {
            s = s.substring(0, s.length() - 1);
        }
        if (s.endsWith(".")) {
            s = s.substring(0, s.length() - 1);
        }
        return s;
    }

    public static <T> T nullDefault(T t, T defaultValue) {
        return Objects.isNull(t) ? defaultValue : t;
    }

    /**
     * 经纬度坐标转换
     */
    public static BigDecimal dmsParse(BigDecimal dms) {
        if (Objects.isNull(dms) || dms.scale() < 4) {
            return dms;
        }

        String s = dms.toPlainString();

        String[] split = s.split("\\.");

        BigDecimal result = new BigDecimal(dms.intValue());

        result = result.add(Toolkit.bigDecimalDivide(split[1].substring(0, 2), 60, 2));
        result = result.add(Toolkit.bigDecimalDivide("0." + split[1].substring(2), 36, dms.scale()));
        result = result.stripTrailingZeros();

        return result;
    }

    /**
     * CGCS2000坐标转 WKT
     */
    public static String cgcs2000ToWKT(String cgcs,int num) {


        return "";
    }

    public static void main(String[] args) {
        BigDecimal bigDecimal = dmsParse(new BigDecimal("90.1913721621"));
        log.info(bigDecimal.toPlainString());
    }
}
